home *** CD-ROM | disk | FTP | other *** search
- page 60,132
- title CDD - Change Drive/Directory
- name CDD
-
- comment #
- CDD.COM V1.00
- -------------------------------------------------------------------------------
- NAME
- cdd Change drive and directory
-
- SYNOPSIS
- CDD [D:][\PATH]
-
- where
- D: is the desired destination drive
- \PATH is the desired path
-
- both drive and path are optional. If the command line is
- blank, a help message is printed on the screen.
-
- DESCRIPTION
- This program is a clone of Bruce B. Thomson program of the same name.
- It will change the drive, directory, or both the drive and directory.
-
- This program is only command line driven. If the command line is
- blank, a quick message on how to properly evoke this program is
- displayed on the screen.
-
- The program checks for the following errors:
- a. The terminal drive is not the same as the one requested.
- b. The termanal path is not the same as the one requested.
- c. The DOS version is 2.0 or above.
-
- In cases (a) and (b) above, CDD will return you to the starting drive
- and path.
-
- CAUTION
- CDD does not check drive or path information before using it.
- If the drive is changed to a floppy with the drive door open, the
- DOS Critical Error Handler is called. A disk must be inserted in
- the drive before the DOS Critical Error Handler will relinquish the
- use of the computer to you. (There is a way to avoid this. Before
- changing drives, use the DOS Absolute Read interrupt to read a sector.
- This interrupt does not evoke the Critical Error Handler so this error
- can be caught before it happens. The major problem is that this really
- slows down the code because of the time it takes to read a sector.
- I will leave the addition of this feature as a programming challange
- for the user.)
-
- AUTHOR
- Raymond Moon - 2 May 87
- Copyright (c) 1987
- ALL RIGHTS RESERVED
-
- HISTORY
- Version - Date - Comments
- 1.00 2 May 87 - Orginal
- #
-
- ;-------------------------------
- ; Required equates and macros.
-
- @EXIT macro RTNCODE ;; Terminate program with return code
- mov ax,4c&RTNCODE&h ; Request term with return code
- int 21h ; Call PC-DOS
- endm
-
- @WRITE macro STRING,FH ;; DOS 2.0+ Write to File Macro
- lea dx,STRING ; Load String addr in DX
- mov cx,STRING&_LEN ; Load String Length in CX
- mov bx,FH ; Load File Handle in BX
- mov ah,40h ; Request DOS write to file/device
- int 21h ; Call PC-DOS
- endm
-
- STDOUT equ 1
- TAB equ 9
- LF equ 0ah
- CR equ 0dh
- _MASK equ 0dfh
- BLNK equ ' '
-
- GRP group CSEG,DSEG,STRING ; All segments in same segment
- assume cs:GRP,ds:GRP,es:GRP,ss:GRP
-
- subttl Data Segments
- page
-
- STRING segment word public 'CONST'
- public DOS_ERR, INVALID_DRIVE,BAD_PATH,LOGO
- public HELP
- DOS_ERR db 'Need DOS2.0+$'
- INVALID_DRIVE db 'Invalid Drive Specification.'
- INVALID_DRIVE_LEN equ $ - INVALID_DRIVE
- BAD_PATH db 'Path Not Found.'
- BAD_PATH_LEN equ $ - BAD_PATH
- LOGO db 'CDD - Change Drive/Directory',CR,LF
- db 'Copyright (c) 1987 MoonWare',CR,LF,LF
- LOGO_LEN equ $ - LOGO
- HELP db 'Evoke CDD with the following command line:',CR,LF,LF
- db TAB,'CDD [D:][\PATH]',CR,LF
- db TAB,TAB,'where',LF,TAB
- db 'D: is the desired drive, optional',CR,LF
- db TAB,TAB,TAB,'\PATH is the desired path, optional',CR,LF
- HELP_LEN equ $ - HELP
- db '***** Raymond Moon - 28 Apr 87 *****'
- STRING ends
-
- DSEG segment word public 'DATA'
- public CURRENT_DRIVE
- CURRENT_DRIVE db ?
- DSEG ends
-
- subttl Code Segment
- page
- CSEG segment para public 'CODE'
-
- ;-----------------------------
- ; Define ARGC, ARGV
-
- PARM struc ; Passed parameter addressing
- dw ?,? ; Saved IP and BP
- ARGC dw ? ; Number of parameters passed
- ARGV dw ? ; Array of pointers.
- PARM ends
-
- ;-----------------------------
- ; Define all procedures as public for debugging
-
- public MAIN, CMDLN, PRINT_HELP
-
- ;-----------------------------
- ; Define Command Line arguments located in the PSP
-
- org 80h
- PARM_LEN db ?
- PARMS db 127 dup(?)
-
- ;-----------------------------
- ; MAIN procedure parses the Command Line
-
- org 100h ; .COM file format
-
- MAIN proc far
- mov ah,30h ; Request DOS version
- int 21h ; Call DOS
- cmp al,2 ; Is it DOS 2.0+
- jae MN0 ; Yes, continue
- lea dx,DOS_ERR ; DX => Error message
- mov ah,9 ; Request print string
- int 21h ; Call DOS
- int 20h ; Terminate program
- MN0: cmp PARM_LEN,0 ; Are there any Command Line arguments
- jne MN1 ; Yes, process them
- call PRINT_HELP ; No, go print HELP
- MN1: xor cx,cx ; Null CX
- push cx ; This ensures last *argv ends in NUL
- mov cl,PARM_LEN ; Get # of bytes in Command Line
- inc cl ; Increment CL to ensure round up
- and cx,0feh ; Force an even count
- mov ax,sp ; Get SP
- mov bp,sp ; Set BP to last byte of Cmd Ln
- sub ax,cx ; Subtract PARM_LEN
- mov sp,ax ; Reset SP, room on Stack
- lea si,PARMS ; Load source addr in SI
- mov di,sp ; Load destin addr in DI
- cld ; Ensure Direction Flag is up
- rep movsb ; Move Command Line onto the Stack
-
- ;-----------------------------
- ; Convert all blanks in the Command Line to Nul
-
- mov bx,bp ; BX points to last byte of Cmd Ln
- MN2: mov al,[bx] ; Get byte
- cmp al,BLNK ; Is it a blank?
- ja MN3 ; No, go set up to get another
- xor al,al ; Nul AX
- mov [bx],al ; Store Nul in [BX]
- MN3: dec bx ; BX point to next byte
- cmp bx,sp ; Are we through yet?
- jnb MN2 ; No, go one mo' 'gin
-
- ;-----------------------------
- ; Build *argv[]. argc kept in CX. DX used as IN_WORD flag
-
- xor cx,cx ; Set CX (argc) to 0
- xor dx,dx ; Set DX to NOT_INWORD
- mov bx,bp ; BX point to last byte
- mov bp,sp ; BP now points to Top of Stack
- MN4: mov al,[bx] ; Get byte
- cmp al,0 ; Is it Nul?
- jne MN5 ; No, it is a char
- cmp dx,0 ; Was the last byte not a char?
- je MN6 ; Yes, go on with the processing
- xor dx,dx ; No, it was a char. Clear INWORD.
- inc cx ; Increment argc
- inc bx ; BX points to Cmd Ln arg
- push bx ; Push addr onto stack
- dec bx ; Reset BX
- jmp short MN6 ; Go set up for another byte
- MN5: inc dx ; Set DX to INWORD
- MN6: dec bx ; BX point to next byte
- cmp bx,bp ; Are we at the 1st byte yet?
- jnb MN4 ; No, go process another
-
- ;-----------------------------
- ; Set up for and call CMDLN
-
- push cx ; Push ARGC onto stack
- call CMDLN ; Call Cmd Ln processor
- MAIN endp
-
- public PRINT_HELP
- PRINT_HELP proc near
- @WRITE HELP,STDOUT ; Print help
- @EXIT 01
- PRINT_HELP endp
-
- public CMDLN
- CMDLN proc near
- push bp ; Save bp
- mov bp,sp ; Set up frame pointer
-
- ;----------------------------
- ; Print LOGO
-
- @WRITE LOGO,STDOUT ; Print LOGO
-
- ;----------------------------
- ; Find ':', break string into drive and path, set flags.
-
- mov di,[bp].ARGV ; ES:DI => command line drive:path
- mov al,':' ; AL = ':'
- mov cx,64 ; Max, count
- repne scasb ; Find ':'
- cmp cx,0 ; Is there a ':'
- jnz CN1 ; ':' found
-
- ;-----------------------------
- ; No ':' found => no drive specification. Go change path.
-
- mov dx,[bp].ARGV ; DS:DX => path
- mov ah,3bh ; Request change current directory
- int 21h ; Call DOS
- jc CN0 ; No error, continue
- @EXIT 00 ; Exit
-
- ;----------------------------
- ; Error in changing path, tell user.
-
- CN0: mov dl,CURRENT_DRIVE ; DL = old drive
- mov ah,0eh ; Request select disk
- int 21h ; Call DOS
- @WRITE BAD_PATH,STDOUT ; Tell user
- @EXIT 02 ; Exit
-
- ;-----------------------------
- ; Change drive. First get current drive.
-
- CN1: mov ah,19h ; Request current drive
- int 21h ; Call DOS
- mov CURRENT_DRIVE,al ; Save it
- mov si,[bp].ARGV ; SI = drive
- and byte ptr [si],_MASK ; Convert to upper case
- mov dl,byte ptr [si] ; DL = drive letter
- sub dl,'A' ; Convert to drive specification
- mov ah,0eh ; Request select disk
- int 21h ; Call DOS
-
- ;----------------------------
- ; Determine if error occurred by comparing current drive with desired
- ; drive.
-
- mov ah,19h ; Request current drive
- int 21h ; Call DOS
- cmp al,dl ; Are they equal?
- je CN2 ; Yes, go change path
-
- ;----------------------------
- ; Error changing drive. Revert to old drive.
-
- mov dl,CURRENT_DRIVE ; DL = old drive
- mov ah,0eh ; Request select disk
- int 21h ; Call DOS
-
- ;--------------------------
- ; Tell user of error and exit.
-
- @WRITE INVALID_DRIVE,STDOUT ; Write error message
- @EXIT 02 ; Exit with error code 2
-
- ;-----------------------------
- ; See if there is a path.
-
- CN2: cmp byte ptr [di],0 ; Is it EOS
- je CN3 ; Yes, go terminate
-
- ;-----------------------------
- ; Change of drive OK, go change path.
-
- mov dx,di ; DS:DX => path
- mov ah,3bh ; Request change current directory
- int 21h ; Call DOS
- jc CN4 ; No error, continue
- CN3: @EXIT 00 ; Exit
-
- ;----------------------------
- ; Return to orginal drive, and tell user of problem.
-
- CN4: mov dl,CURRENT_DRIVE ; DL = old drive
- mov ah,0eh ; Request select disk
- int 21h ; Call DOS
- @WRITE BAD_PATH,STDOUT ; Tell user
- @EXIT 02 ; Exit
-
- CMDLN endp
-
- CSEG ends
-
- end MAIN
-